package nz.ac.massey.doi_information_extractor.gui;

import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Desktop;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

import javax.swing.DefaultComboBoxModel;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.LayoutStyle;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import nz.ac.massey.doi_information_extractor.data.Author;
import nz.ac.massey.doi_information_extractor.data.AuthorList;
import nz.ac.massey.doi_information_extractor.data.Publication;
import nz.ac.massey.doi_information_extractor.main.Main;


/**
 *
 * @author Team Awesome
 */
@SuppressWarnings("serial")
public class Gui extends AbstractGui implements KeyListener, ActionListener, ClipboardOwner, FocusListener, ListSelectionListener, MouseListener, WindowListener{

	private Main main;

	/**
	 * Constructor for Gui
	 *
	 * @param main - the main class object
	 */
	public Gui(Main main) {
		super();
		this.main = main;
		enableGui(false);
	}

	private Publication currentPublication;
	private JPanel conferenceCard;
    private JButton addAuthorButton;
    private JTextField articleTitleField;
    private JLabel articleTitleLabel;
    private JList authorsJList;
    private JPanel bookCard;
    private JTextField bookDateField;
    private JLabel bookDateLabel;
    private JTextField bookEditionField;
    private JLabel bookEditionLabel;
    private JTextField bookEditorsField;
    private JLabel bookEditorsLabel;
    private JTextField bookIssnIsbnField;
    private JLabel bookIssnIsbnLabel;
    private JTextField bookPagesField;
    private JLabel bookPagesLabel;
    private JTextField bookTitleField;
    private JLabel bookTitleLabel;
    private JTextField bookUrlField;
    private JLabel bookUrlLabel;
    private JLabel characterCountLabel;
    private JTextField conferenceDateField;
    private JLabel conferenceDateLabel;
    private JTextField conferenceDatesField;
    private JLabel conferenceDatesLabel;
    private JTextField conferenceEditionField;
    private JLabel conferenceEditionLabel;
    private JTextField conferenceEditorsField;
    private JTextField conferenceIssnIsbnField;
    private JLabel conferenceIssnIsbnLabel;
    private JTextField conferenceLocationField;
    private JLabel conferenceLocationLabel;
    private JTextField conferencePagesField;
    private JLabel conferencePagesLabel;
    private JTextField conferenceUrlField;
    private JLabel conferenceUrlLabel;
    private JCheckBox confidentialBox;
    private JTextArea descriptionArea;
    private JLabel descriptionLabel;
    private JTextField doiField;
    private JLabel doiLabel;
    private JLabel editorsLabel;
    private JMenuItem exitMenuItem;
    private JMenu fileMenu;
    private JMenu helpMenu;
    private JMenuItem helpMenuItem;
    private JTextField issnIsbnField;
    private JLabel issnIsbnLabel;
    private JScrollPane jScrollPane1;
    private JScrollPane jScrollPane2;
    private JSeparator jSeparator1;
    private JSeparator jSeparator2;
    private JPanel journalCard;
    private JTextField journalDateField;
    private JLabel journalDateLabel;
    private JTextField journalIssueField;
    private JLabel journalPagesLabel;
    private JTextField journalPublisherField;
    private JLabel journalPublisherLabel;
    private JTextField journalTitleField;
    private JLabel journalTitleLabel;
    private JTextField journalUrlField;
    private JLabel journalUrlLabel;
    private JTextField journalVolumeField;
    private JLabel journalVolumeLabel;
    private JTextField keywordsField;
    private JLabel keywordsLabel;
    private JMenuBar mainMenuBar;
    private JButton moveAuthorDownButton;
    private JButton moveAuthorUpButton;
    private JMenuItem newMenuItem;
    private JMenuItem openMenuItem;
    private JMenuItem outputMenuItem;
    private JTextField pagesField;
    private JTextField paperTitleField;
    private JLabel paperTitleLabel;
    private JTextField placePubishedField;
    private JLabel placePublishedLabel;
    private JTextField proceedingsField;
    private JLabel proceedingsLabel;
    private JProgressBar progressBar;
    private JComboBox publicationTypeDropDown;
    private JTextField publisherField;
    private JLabel publisherLabel;
    private JCheckBox qaBox;
    private JButton removeAuthorButton;
    private JComboBox researchProfCommDropDown;
    private JTextField rimsIdField;
    private JLabel rimsIdLabel;
    private JMenuItem saveMenuItem;
    private JButton setAuthorButton;
    private JButton setSubmitterButton;
    private JMenuItem settingsMenuItem;
    private JPanel swapPanel;
    private JLabel typeOfResearchLabel;
    private JLabel volumeIssueLabel;
    private JMenu editMenu;
    private JCheckBoxMenuItem copyModeMenuItem;
    private JMenuItem deleteMenuItem;

    /**
     * Initializes the components of the interface
     */
    protected void initComponents() {
    	editMenu = new JMenu();
        copyModeMenuItem = new JCheckBoxMenuItem();
        deleteMenuItem = new JMenuItem();

        publicationTypeDropDown = new JComboBox();
        jSeparator1 = new JSeparator();
        rimsIdLabel = new JLabel();
        rimsIdField = new JTextField();
        typeOfResearchLabel = new JLabel();
        qaBox = new JCheckBox();
        confidentialBox = new JCheckBox();
        jSeparator2 = new JSeparator();
        jScrollPane1 = new JScrollPane();
        authorsJList = new JList();
        setAuthorButton = new JButton();
        swapPanel = new JPanel();
        bookCard = new JPanel();
        bookTitleField = new JTextField();
        bookTitleLabel = new JLabel();
        publisherLabel = new JLabel();
        publisherField = new JTextField();
        bookUrlLabel = new JLabel();
        bookEditionLabel = new JLabel();
        bookEditionField = new JTextField();
        bookPagesField = new JTextField();
        bookPagesLabel = new JLabel();
        bookDateLabel = new JLabel();
        bookDateField = new JTextField();
        bookIssnIsbnLabel = new JLabel();
        bookIssnIsbnField = new JTextField();
        placePubishedField = new JTextField();
        placePublishedLabel = new JLabel();
        bookEditorsField = new JTextField();
        bookEditorsLabel = new JLabel();
        bookUrlField = new JTextField();
        conferenceCard = new JPanel();
        paperTitleLabel = new JLabel();
        paperTitleField = new JTextField();
        proceedingsLabel = new JLabel();
        proceedingsField = new JTextField();
        conferenceLocationLabel = new JLabel();
        conferenceLocationField = new JTextField();
        conferenceDatesLabel = new JLabel();
        conferenceUrlLabel = new JLabel();
        editorsLabel = new JLabel();
        conferenceEditorsField = new JTextField();
        conferenceDatesField = new JTextField();
        conferenceIssnIsbnField = new JTextField();
        conferenceIssnIsbnLabel = new JLabel();
        conferenceDateField = new JTextField();
        conferenceDateLabel = new JLabel();
        conferencePagesLabel = new JLabel();
        conferencePagesField = new JTextField();
        conferenceEditionField = new JTextField();
        conferenceEditionLabel = new JLabel();
        conferenceUrlField = new JTextField();
        journalCard = new JPanel();
        journalTitleLabel = new JLabel();
        articleTitleLabel = new JLabel();
        journalUrlLabel = new JLabel();
        journalTitleField = new JTextField();
        articleTitleField = new JTextField();
        journalVolumeLabel = new JLabel();
        journalPublisherField = new JTextField();
        journalPublisherLabel = new JLabel();
        journalVolumeField = new JTextField();
        volumeIssueLabel = new JLabel();
        journalIssueField = new JTextField();
        journalDateLabel = new JLabel();
        journalDateField = new JTextField();
        issnIsbnLabel = new JLabel();
        issnIsbnField = new JTextField();
        journalPagesLabel = new JLabel();
        pagesField = new JTextField();
        journalUrlField = new JTextField();
        setSubmitterButton = new JButton();
        descriptionLabel = new JLabel();
        jScrollPane2 = new JScrollPane();
        descriptionArea = new JTextArea();
        keywordsLabel = new JLabel();
        keywordsField = new JTextField();
        characterCountLabel = new JLabel();
        researchProfCommDropDown = new JComboBox();
        progressBar = new JProgressBar();
        doiLabel = new JLabel();
        doiField = new JTextField();
        addAuthorButton = new JButton();
        removeAuthorButton = new JButton();
        moveAuthorUpButton = new JButton();
        moveAuthorDownButton = new JButton();
        mainMenuBar = new JMenuBar();
        fileMenu = new JMenu();
        newMenuItem = new JMenuItem();
        openMenuItem = new JMenuItem();
        saveMenuItem = new JMenuItem();
        outputMenuItem = new JMenuItem();
        exitMenuItem = new JMenuItem();
        helpMenu = new JMenu();
        settingsMenuItem = new JMenuItem();
        helpMenuItem = new JMenuItem();

        publicationTypeDropDown.setModel(new DefaultComboBoxModel(new String[] { "Journal", "Book", "Conference" }));
        publicationTypeDropDown.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                String selectedType = (String)publicationTypeDropDown.getSelectedItem();
                if(currentPublication != null){
                    currentPublication.setPublicationType(selectedType);
                }
                setPublication(currentPublication);

                CardLayout c1 = (CardLayout) (swapPanel.getLayout());
                if(selectedType.equals("Journal")){
                    c1.show(swapPanel, "journalCard");
                }
                else if(selectedType.equals("Book")){
                    c1.show(swapPanel, "bookCard");
                }
                else if(selectedType.equals("Conference")){
                    c1.show(swapPanel, "conferenceCard");
                }
            }
        });

        rimsIdLabel.setText("RIMS ID:");

        typeOfResearchLabel.setText("Type of Research:");

        qaBox.setText("Quality Assured");

        confidentialBox.setText("Confidential");

        jScrollPane1.setViewportView(authorsJList);

        setAuthorButton.setText("Set Author");

        swapPanel.setLayout(new CardLayout());

        bookTitleLabel.setText("Book Title:");

        publisherLabel.setText("Publisher:");

        bookUrlLabel.setText("URL:");
        bookUrlLabel.setText("<html><u>URL:</u></html>");
        bookUrlLabel.setForeground(Color.BLUE);

        bookEditionLabel.setText("Edition:");

        bookPagesLabel.setText("Pages:");

        bookDateLabel.setText("Date:");

        bookIssnIsbnLabel.setText("ISSN/ISBN:");

        placePublishedLabel.setText("Place Published:");

        bookEditorsLabel.setText("Editors:");

        GroupLayout bookCardLayout = new GroupLayout(bookCard);
        bookCard.setLayout(bookCardLayout);
        bookCardLayout.setHorizontalGroup(
            bookCardLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(bookCardLayout.createSequentialGroup()
                .addGroup(bookCardLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addComponent(bookTitleLabel)
                    .addComponent(publisherLabel)
                    .addComponent(placePublishedLabel)
                    .addComponent(bookUrlLabel)
                    .addComponent(bookEditorsLabel)
                    .addComponent(bookEditionLabel)
                    .addComponent(bookIssnIsbnLabel))
                .addGap(36, 36, 36)
                .addGroup(bookCardLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addComponent(bookEditorsField, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 555, Short.MAX_VALUE)
                    .addComponent(bookUrlField, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 555, Short.MAX_VALUE)
                    .addComponent(bookTitleField, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 555, Short.MAX_VALUE)
                    .addComponent(publisherField, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 555, Short.MAX_VALUE)
                    .addComponent(placePubishedField, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 555, Short.MAX_VALUE)
                    .addGroup(bookCardLayout.createSequentialGroup()
                        .addGroup(bookCardLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false)
                            .addComponent(bookIssnIsbnField)
                            .addComponent(bookEditionField, GroupLayout.PREFERRED_SIZE, 98, GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(bookCardLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
                            .addComponent(bookDateLabel)
                            .addComponent(bookPagesLabel))
                        .addGap(18, 18, 18)
                        .addGroup(bookCardLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false)
                            .addComponent(bookDateField)
                            .addComponent(bookPagesField, GroupLayout.PREFERRED_SIZE, 91, GroupLayout.PREFERRED_SIZE))))
                .addContainerGap())
        );
        bookCardLayout.setVerticalGroup(
            bookCardLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(bookCardLayout.createSequentialGroup()
                .addGroup(bookCardLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(bookTitleField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(bookTitleLabel))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(bookCardLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(publisherLabel)
                    .addComponent(publisherField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(bookCardLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(placePublishedLabel)
                    .addComponent(placePubishedField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                .addGap(9, 9, 9)
                .addGroup(bookCardLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(bookUrlLabel)
                    .addComponent(bookUrlField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(bookCardLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(bookEditorsField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(bookEditorsLabel))
                .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(bookCardLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addGroup(bookCardLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                        .addComponent(bookPagesLabel)
                        .addComponent(bookPagesField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                    .addGroup(bookCardLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                        .addComponent(bookEditionField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                        .addComponent(bookEditionLabel)))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(bookCardLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addGroup(bookCardLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                        .addComponent(bookDateField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                        .addComponent(bookDateLabel))
                    .addGroup(bookCardLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                        .addComponent(bookIssnIsbnField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                        .addComponent(bookIssnIsbnLabel)))
                .addGap(115, 115, 115))
        );

        swapPanel.add(bookCard, "bookCard");

        paperTitleLabel.setText("Paper Title:");

        proceedingsLabel.setText("Proceedings Title:");

        conferenceLocationLabel.setText("Conference Location:");

        conferenceDatesLabel.setText("Conference Dates:");

        conferenceUrlLabel.setText("URL:");
        conferenceUrlLabel.setText("<html><u>URL:</u></html>");
        conferenceUrlLabel.setForeground(Color.blue);

        editorsLabel.setText("Editors:");

        conferenceIssnIsbnLabel.setText("ISSN/ISBN:");

        conferenceDateLabel.setText("Date:");

        conferencePagesLabel.setText("Pages:");

        conferenceEditionLabel.setText("Edition:");

        GroupLayout conferenceCardLayout = new GroupLayout(conferenceCard);
        conferenceCard.setLayout(conferenceCardLayout);
        conferenceCardLayout.setHorizontalGroup(
            conferenceCardLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(conferenceCardLayout.createSequentialGroup()
                .addGroup(conferenceCardLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addComponent(paperTitleLabel)
                    .addComponent(proceedingsLabel)
                    .addComponent(conferenceLocationLabel)
                    .addComponent(conferenceDatesLabel)
                    .addComponent(conferenceUrlLabel)
                    .addComponent(editorsLabel)
                    .addComponent(conferenceIssnIsbnLabel)
                    .addComponent(conferenceEditionLabel))
                .addGap(10, 10, 10)
                .addGroup(conferenceCardLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addGroup(conferenceCardLayout.createSequentialGroup()
                        .addGroup(conferenceCardLayout.createParallelGroup(GroupLayout.Alignment.TRAILING)
                            .addComponent(conferenceEditorsField, GroupLayout.DEFAULT_SIZE, 555, Short.MAX_VALUE)
                            .addComponent(conferenceUrlField, GroupLayout.DEFAULT_SIZE, 555, Short.MAX_VALUE)
                            .addComponent(proceedingsField, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 555, Short.MAX_VALUE)
                            .addComponent(conferenceDatesField, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 555, Short.MAX_VALUE)
                            .addComponent(conferenceLocationField, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 555, Short.MAX_VALUE)
                            .addComponent(paperTitleField, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 555, Short.MAX_VALUE))
                        .addContainerGap())
                    .addGroup(conferenceCardLayout.createSequentialGroup()
                        .addGroup(conferenceCardLayout.createParallelGroup(GroupLayout.Alignment.TRAILING, false)
                            .addComponent(conferenceIssnIsbnField, GroupLayout.Alignment.LEADING)
                            .addComponent(conferenceEditionField, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 128, Short.MAX_VALUE))
                        .addGap(18, 18, 18)
                        .addGroup(conferenceCardLayout.createParallelGroup(GroupLayout.Alignment.TRAILING)
                            .addComponent(conferencePagesLabel)
                            .addComponent(conferenceDateLabel))
                        .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(conferenceCardLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false)
                            .addComponent(conferenceDateField)
                            .addComponent(conferencePagesField, GroupLayout.DEFAULT_SIZE, 116, Short.MAX_VALUE))
                        .addGap(260, 260, 260))))
        );
        conferenceCardLayout.setVerticalGroup(
            conferenceCardLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(conferenceCardLayout.createSequentialGroup()
                .addGroup(conferenceCardLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(paperTitleField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(paperTitleLabel))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(conferenceCardLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(proceedingsField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(proceedingsLabel))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(conferenceCardLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(conferenceLocationField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(conferenceLocationLabel))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(conferenceCardLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(conferenceDatesField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(conferenceDatesLabel, 0, 0, Short.MAX_VALUE))
                .addGap(8, 8, 8)
                .addGroup(conferenceCardLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(conferenceUrlField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(conferenceUrlLabel))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(conferenceCardLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(conferenceEditorsField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(editorsLabel))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(conferenceCardLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(conferenceEditionLabel)
                    .addComponent(conferenceEditionField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(conferencePagesLabel)
                    .addComponent(conferencePagesField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(conferenceCardLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(conferenceIssnIsbnLabel)
                    .addComponent(conferenceIssnIsbnField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(conferenceDateLabel)
                    .addComponent(conferenceDateField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                .addGap(87, 87, 87))
        );

        swapPanel.add(conferenceCard, "conferenceCard");

        journalCard.setPreferredSize(new java.awt.Dimension(661, 275));

        journalTitleLabel.setText("Journal Title:");

        articleTitleLabel.setText("Article Title:");

        journalUrlLabel.setText("URL:");
        journalUrlLabel.setText("<html><u>URL:</u></html>");
        journalUrlLabel.setForeground(Color.blue);

        journalVolumeLabel.setText("Volume:");

        journalPublisherLabel.setText("Publisher:");

        volumeIssueLabel.setText("Issue:");

        journalDateLabel.setText("Date:");

        issnIsbnLabel.setText("ISSN/ISBN:");

        journalPagesLabel.setText("Pages:");

        GroupLayout journalCardLayout = new GroupLayout(journalCard);
        journalCard.setLayout(journalCardLayout);
        journalCardLayout.setHorizontalGroup(
            journalCardLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(journalCardLayout.createSequentialGroup()
                .addGroup(journalCardLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addComponent(journalTitleLabel)
                    .addComponent(articleTitleLabel, GroupLayout.PREFERRED_SIZE, 71, GroupLayout.PREFERRED_SIZE)
                    .addComponent(journalPublisherLabel)
                    .addComponent(journalUrlLabel)
                    .addComponent(issnIsbnLabel)
                    .addComponent(journalVolumeLabel))
                .addGap(40, 40, 40)
                .addGroup(journalCardLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addGroup(journalCardLayout.createSequentialGroup()
                        .addGroup(journalCardLayout.createParallelGroup(GroupLayout.Alignment.TRAILING, false)
                            .addComponent(issnIsbnField, GroupLayout.Alignment.LEADING)
                            .addComponent(journalVolumeField, GroupLayout.Alignment.LEADING, GroupLayout.PREFERRED_SIZE, 100, GroupLayout.PREFERRED_SIZE))
                        .addGap(18, 18, 18)
                        .addGroup(journalCardLayout.createParallelGroup(GroupLayout.Alignment.TRAILING)
                            .addComponent(journalPagesLabel)
                            .addComponent(volumeIssueLabel))
                        .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(journalCardLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false)
                            .addComponent(pagesField)
                            .addComponent(journalIssueField, GroupLayout.PREFERRED_SIZE, 100, GroupLayout.PREFERRED_SIZE))
                        .addGap(18, 18, 18)
                        .addComponent(journalDateLabel)
                        .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(journalDateField, GroupLayout.PREFERRED_SIZE, 105, GroupLayout.PREFERRED_SIZE))
                    .addComponent(journalTitleField, GroupLayout.DEFAULT_SIZE, 557, Short.MAX_VALUE)
                    .addComponent(articleTitleField, GroupLayout.DEFAULT_SIZE, 557, Short.MAX_VALUE)
                    .addComponent(journalPublisherField, GroupLayout.DEFAULT_SIZE, 557, Short.MAX_VALUE)
                    .addComponent(journalUrlField, GroupLayout.DEFAULT_SIZE, 557, Short.MAX_VALUE))
                .addContainerGap())
        );
        journalCardLayout.setVerticalGroup(
            journalCardLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(journalCardLayout.createSequentialGroup()
                .addGroup(journalCardLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(journalTitleLabel)
                    .addComponent(journalTitleField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(journalCardLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(articleTitleField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(articleTitleLabel))
                .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(journalCardLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(journalPublisherField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(journalPublisherLabel))
                .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(journalCardLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(journalUrlLabel)
                    .addComponent(journalUrlField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(journalCardLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(journalVolumeField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(journalDateLabel)
                    .addComponent(journalDateField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(journalIssueField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(volumeIssueLabel, GroupLayout.PREFERRED_SIZE, 17, GroupLayout.PREFERRED_SIZE)
                    .addComponent(journalVolumeLabel))
                .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(journalCardLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(issnIsbnField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(pagesField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(journalPagesLabel)
                    .addComponent(issnIsbnLabel))
                .addGap(122, 122, 122))
        );

        swapPanel.add(journalCard, "journalCard");

        setSubmitterButton.setText("Set Submitter");

        descriptionLabel.setText("Description:");

        descriptionArea.setColumns(20);
        descriptionArea.setLineWrap(true);
        descriptionArea.setRows(5);
        jScrollPane2.setViewportView(descriptionArea);

        keywordsLabel.setText("Keywords:");

        characterCountLabel.setText("0/1012");

        researchProfCommDropDown.setModel(new DefaultComboBoxModel(new String[] { "Research", "Professional/Community" }));

        doiLabel.setText("DOI:");

        doiField.setEditable(false);

        addAuthorButton.setText("Add Author");

        removeAuthorButton.setText("Remove Author");

        moveAuthorUpButton.setText("+");

        moveAuthorDownButton.setText("-");

        fileMenu.setText("File");

        newMenuItem.setText("New");
        fileMenu.add(newMenuItem);

        openMenuItem.setText("Open");
        fileMenu.add(openMenuItem);

        deleteMenuItem.setText("Delete");
        fileMenu.add(deleteMenuItem);
        deleteMenuItem.setEnabled(false);

        saveMenuItem.setText("Save");
        fileMenu.add(saveMenuItem);

        outputMenuItem.setText("PDF Output");
        fileMenu.add(outputMenuItem);
        outputMenuItem.setEnabled(false);

        exitMenuItem.setText("Exit");
        exitMenuItem.addActionListener(this);
        fileMenu.add(exitMenuItem);

        mainMenuBar.add(fileMenu);

        editMenu.setText("Edit");
        copyModeMenuItem.setText("Copy Mode");
        editMenu.add(copyModeMenuItem);

        mainMenuBar.add(editMenu);

        helpMenu.setText("Help");

        settingsMenuItem.setText("Settings");
        helpMenuItem.setText("Help");

        helpMenu.add(settingsMenuItem);
        helpMenu.add(helpMenuItem);

        mainMenuBar.add(helpMenu);

        setJMenuBar(mainMenuBar);

        GroupLayout layout = new GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING)
                    .addComponent(swapPanel, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 678, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(rimsIdLabel)
                                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, false)
                                    .addComponent(rimsIdField)
                                    .addComponent(doiField, GroupLayout.DEFAULT_SIZE, 250, Short.MAX_VALUE)))
                            .addComponent(doiLabel))
                        .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                            .addComponent(typeOfResearchLabel)
                            .addComponent(qaBox))
                        .addGap(18, 18, 18)
                        .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                            .addComponent(confidentialBox)
                            .addComponent(researchProfCommDropDown, 0, 252, Short.MAX_VALUE)))
                    .addComponent(jSeparator2, GroupLayout.DEFAULT_SIZE, 678, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                            .addComponent(setSubmitterButton, GroupLayout.DEFAULT_SIZE, 117, Short.MAX_VALUE)
                            .addComponent(setAuthorButton, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 117, Short.MAX_VALUE)
                            .addComponent(addAuthorButton, GroupLayout.DEFAULT_SIZE, 117, Short.MAX_VALUE)
                            .addComponent(removeAuthorButton, GroupLayout.DEFAULT_SIZE, 117, Short.MAX_VALUE))
                        .addGap(18, 18, 18)
                        .addComponent(jScrollPane1, GroupLayout.PREFERRED_SIZE, 496, GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, false)
                            .addComponent(moveAuthorDownButton, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(moveAuthorUpButton, GroupLayout.DEFAULT_SIZE, 41, Short.MAX_VALUE)))
                    .addGroup(GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                        .addComponent(jSeparator1, GroupLayout.DEFAULT_SIZE, 668, Short.MAX_VALUE)
                        .addGap(10, 10, 10))
                    .addGroup(GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                        .addComponent(publicationTypeDropDown, 0, 177, Short.MAX_VALUE)
                        .addGap(501, 501, 501))
                    .addGroup(GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING)
                                .addComponent(characterCountLabel)
                                .addComponent(descriptionLabel))
                            .addComponent(keywordsLabel))
                        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                            .addComponent(keywordsField, GroupLayout.DEFAULT_SIZE, 617, Short.MAX_VALUE)
                            .addComponent(jScrollPane2, GroupLayout.DEFAULT_SIZE, 617, Short.MAX_VALUE)))
                    .addComponent(progressBar, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 678, Short.MAX_VALUE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(doiLabel)
                    .addComponent(doiField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(typeOfResearchLabel)
                    .addComponent(researchProfCommDropDown, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(rimsIdLabel)
                    .addComponent(rimsIdField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(qaBox)
                    .addComponent(confidentialBox))
                .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jSeparator2, GroupLayout.PREFERRED_SIZE, 10, GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, false)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(setAuthorButton)
                        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(setSubmitterButton)
                        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(addAuthorButton)
                        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(removeAuthorButton))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(moveAuthorUpButton)
                        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(moveAuthorDownButton))
                    .addComponent(jScrollPane1, GroupLayout.PREFERRED_SIZE, 110, GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jSeparator1, GroupLayout.PREFERRED_SIZE, 10, GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(publicationTypeDropDown, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addGap(8, 8, 8)
                .addComponent(swapPanel, GroupLayout.PREFERRED_SIZE, 267, GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(descriptionLabel)
                        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(characterCountLabel))
                    .addComponent(jScrollPane2, GroupLayout.PREFERRED_SIZE, 76, GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(keywordsLabel)
                    .addComponent(keywordsField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(progressBar, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        setListeners();
        setCardLayout((String)publicationTypeDropDown.getSelectedItem());
        this.setTitle("DOI Information Extractor");
        pack();
        this.setVisible(true);

    }

    /**
     * Adds listeners to the objects that require them on the GUI
     */
	private void setListeners() {
		this.addWindowListener(this);
		authorsJList.addListSelectionListener(this);

		descriptionArea.addKeyListener(this);
		conferenceUrlField.addMouseListener(this);
		bookUrlLabel.addMouseListener(this);
		journalUrlLabel.addMouseListener(this);
		setAuthorButton.addActionListener(this);
		setSubmitterButton.addActionListener(this);
		addAuthorButton.addActionListener(this);
		removeAuthorButton.addActionListener(this);
		moveAuthorUpButton.addActionListener(this);
		moveAuthorDownButton.addActionListener(this);
		newMenuItem.addActionListener(this);
		openMenuItem.addActionListener(this);
		saveMenuItem.addActionListener(this);
		outputMenuItem.addActionListener(this);
		settingsMenuItem.addActionListener(this);
		helpMenuItem.addActionListener(this);
		deleteMenuItem.addActionListener(this);

		articleTitleField.addFocusListener(this);
		bookDateField.addFocusListener(this);
		bookEditionField.addFocusListener(this);
		bookEditorsField.addFocusListener(this);
		bookIssnIsbnField.addFocusListener(this);
		bookPagesField.addFocusListener(this);
		bookTitleField.addFocusListener(this);
		bookUrlField.addFocusListener(this);
		conferenceDateField.addFocusListener(this);
		conferenceDatesField.addFocusListener(this);
		conferenceEditionField.addFocusListener(this);
		conferenceEditorsField.addFocusListener(this);
		conferenceIssnIsbnField.addFocusListener(this);
		conferenceLocationField.addFocusListener(this);
		conferencePagesField.addFocusListener(this);
		conferenceUrlField.addFocusListener(this);
		descriptionArea.addFocusListener(this);
		doiField.addFocusListener(this);
		issnIsbnField.addFocusListener(this);

		journalDateField.addFocusListener(this);
		journalIssueField.addFocusListener(this);
		journalPublisherField.addFocusListener(this);
		journalTitleField.addFocusListener(this);
		journalUrlField.addFocusListener(this);
		journalVolumeField.addFocusListener(this);
		keywordsField.addFocusListener(this);
		pagesField.addFocusListener(this);
		paperTitleField.addFocusListener(this);
		placePubishedField.addFocusListener(this);
		proceedingsField.addFocusListener(this);
		publisherField.addFocusListener(this);
		rimsIdField.addFocusListener(this);
	}

	/**
	 * Returns doi in the doiField
	 */
	@Override
	public String getDoi() {
		return doiField.getText();
	}

	/**
	 * Returns a publication with the relevant information contained in the GUI
	 */
	@Override
	public Publication getPublication() {
		if(currentPublication == null){
			return null;
		}

		String publicationType = (String)publicationTypeDropDown.getSelectedItem();
		Publication publicationToReturn;

		Boolean researchOrProf = true;
		if(researchProfCommDropDown.getSelectedIndex() == 1)
		{
			researchOrProf = false;
		}

		// For referenece of layout of a publication.
		/*Publication pub = new Publication(description, publicationType,
				pageNumbers, publicationTitle, qualityAssured, confidential,
				researchOrProfCom, volumeNumber, articleTitle, date, url, issn,
				authors, publisher, keywords, conferenceLocation,
				conferenceDates, publisherLocation, editors, journalEdition,
				journalNumber, doi, publicationId, rimsId);*/

		if(publicationType.equals("Journal")){
			publicationToReturn = new Publication(descriptionArea.getText(),
					publicationType, pagesField.getText(),
					journalTitleField.getText(), qaBox.isSelected(),
					confidentialBox.isSelected(), researchOrProf,
					journalVolumeField.getText(), articleTitleField.getText(),
					journalDateField.getText(), journalUrlField.getText(),
					issnIsbnField.getText(), currentPublication.getAuthors(),
					currentPublication.getPublisher(), keywordsField.getText(),
					currentPublication.getConferenceLocation(),
					currentPublication.getConferenceDates(),
					currentPublication.getPublisherLocation(),
					currentPublication.getEditors(),
					journalIssueField.getText(),
					"0", doiField.getText(),
					currentPublication.getPublicationId(), rimsIdField.getText());
		}
		else if(publicationType.equals("Book")){
			publicationToReturn = new Publication(descriptionArea.getText(), publicationType,
					bookPagesField.getText(), bookTitleField.getText(), qaBox.isSelected(),
					confidentialBox.isSelected(), researchOrProf,
					currentPublication.getVolumeNumber(),
					publisherField.getText(), bookDateField.getText(),
					bookUrlField.getText(), bookIssnIsbnField.getText(),
					currentPublication.getAuthors(),
					currentPublication.getPublisher(), keywordsField.getText(),
					currentPublication.getConferenceLocation(),
					currentPublication.getConferenceDates(),
					placePubishedField.getText(), bookEditorsField.getText(),
					bookEditionField.getText(),
					currentPublication.getJournalNumber(), doiField.getText(), currentPublication.getPublicationId(),
					rimsIdField.getText());
		}
		else if(publicationType.equals("Conference")){
			publicationToReturn = new Publication(descriptionArea.getText(),
					publicationType, conferencePagesField.getText(),
					paperTitleField.getText(), qaBox.isSelected(),
					confidentialBox.isSelected(), researchOrProf,
					currentPublication.getVolumeNumber(),
					proceedingsField.getText(), conferenceDateField.getText(),
					conferenceUrlField.getText(),
					conferenceIssnIsbnField.getText(),
					currentPublication.getAuthors(),
					currentPublication.getPublisher(), keywordsField.getText(),
					conferenceLocationField.getText(),
					conferenceDateField.getText(),
					currentPublication.getPublisherLocation(),
					conferenceEditorsField.getText(),
					conferenceEditionField.getText(),
					currentPublication.getJournalNumber(), doiField.getText(),
					currentPublication.getPublicationId(), rimsIdField.getText());
		}
		else{
			publicationToReturn = null;
		}
		return publicationToReturn;
	}

	/**
	 * Get author at selected place in the authors list
	 */
	@Override
	public Author getSelectedAuthor() {
		if(authorsJList.getSelectedIndex() == -1)
			return null;

		return currentPublication.getAuthors().get(authorsJList.getSelectedIndex());
	}

	/**
	 * Sets the selected author in the list to the database
	 */
	@Override
	public void setSelectedAuthor(Author author) {
		currentPublication.getAuthors().set(authorsJList.getSelectedIndex(), author);
		setAuthors();
	}

	/**
	 * Sets the current publication to the GUI
	 */
	@Override
	public void setPublication(Publication publication) {
		if(publication == null){
			currentPublication = null;
			clearGui();
			deleteMenuItem.setEnabled(false);
			outputMenuItem.setEnabled(false);
			return;
		}

		if(publication.getPublicationId() >= 0){
			deleteMenuItem.setEnabled(true);
		}else{
			deleteMenuItem.setEnabled(false);
		}
		outputMenuItem.setEnabled(true);

		currentPublication = publication;
		String type = (String)publicationTypeDropDown.getSelectedItem();

		if(type.equals("Journal")){
			setCardLayout(type);
			journalTitleField.setText(publication.getPublicationTitle());
			articleTitleField.setText(publication.getArticleTitle());
			journalUrlField.setText(publication.getUrl());
			journalIssueField.setText(publication.getEdition());
			pagesField.setText(publication.getPageNumbers());
			journalDateField.setText(publication.getDate());
			issnIsbnField.setText(publication.getIssn());
			journalVolumeField.setText(publication.getVolumeNumber());
			journalPublisherField.setText(publication.getPublisher());
		}
		else if(type.equals("Book")){
			bookTitleField.setText(publication.getPublicationTitle());
			publisherField.setText(publication.getPublisher());
			placePubishedField.setText(publication.getPublisherLocation());
			bookUrlField.setText(publication.getUrl());
			bookEditorsField.setText(publication.getEditors());
			bookEditionField.setText(publication.getEdition());
			bookIssnIsbnField.setText(publication.getIssn());
			bookPagesField.setText(publication.getPageNumbers());
			bookDateField.setText(publication.getDate());
			publisherField.setText(publication.getPublisher());
		}
		else if(type.equals("Conference")){
			paperTitleField.setText(publication.getPublicationTitle());
			proceedingsField.setText(publication.getArticleTitle());
			conferenceLocationField.setText(publication.getConferenceLocation());
			conferenceDatesField.setText(publication.getConferenceDates());
			conferenceUrlField.setText(publication.getUrl());
			conferenceEditorsField.setText(publication.getEditors());
			conferenceEditionField.setText(publication.getEdition());
			conferenceIssnIsbnField.setText(publication.getIssn());
			conferencePagesField.setText(publication.getPageNumbers());
			conferenceDateField.setText(publication.getDate());
		}

		doiField.setText(publication.getDoi());
		setAuthors();
		descriptionArea.setText(publication.getDescription());
		keywordsField.setText(publication.getKeywords());
		if(publication.getResearchOrProfCom()){
			researchProfCommDropDown.setSelectedItem((String)"Research");
		}
		else{
			researchProfCommDropDown.setSelectedItem((String)"Professional/Community");
		}
		qaBox.setSelected(publication.getQualityAssured());
		confidentialBox.setSelected(publication.getConfidential());
		rimsIdField.setText(publication.getRimsId());
		setCharacterCountLabel();
	}

	/**
	 * Counts the characters in the descriptionArea and displays the count in a label
	 */
	@Override
	public void keyPressed(KeyEvent e) {
		if(descriptionArea.getText().length() > 1012){
			descriptionArea.setText(descriptionArea.getText().substring(0, 1012));
		}

		currentPublication.setDescription(descriptionArea.getText());
		setCharacterCountLabel();
	}

	/**
	 * Counts the characters in the descriptionArea and displays the count in a label
	 */
	@Override
	public void keyReleased(KeyEvent e) {
		if(descriptionArea.getText().length() > 1012){
			descriptionArea.setText(descriptionArea.getText().substring(0, 1012));
		}

		currentPublication.setDescription(descriptionArea.getText());
		setCharacterCountLabel();
	}

	/**
	 * Counts the characters in the descriptionArea and displays the count in a label
	 */
	@Override
	public void keyTyped(KeyEvent e) {
		if(descriptionArea.getText().length() > 1012){
			descriptionArea.setText(descriptionArea.getText().substring(0, 1012));
		}

		currentPublication.setDescription(descriptionArea.getText());
		setCharacterCountLabel();
	}

	/**
	 * Sets the label to the count
	 */
	private void setCharacterCountLabel(){
		if(currentPublication == null){
			characterCountLabel.setText(Integer.toString(descriptionArea.getText().length()));
		}
		else{
			characterCountLabel.setText(Integer.toString(currentPublication.getDescription().length()) + "/1012");
		}
	}

	/**
	 * Set the current card depending on the related item in the publicationDropDownBox
	 * @param selectedType
	 */
	private void setCardLayout(String selectedType){
		CardLayout c1 = (CardLayout) (swapPanel.getLayout());
        if(selectedType.equals("Journal")){
            c1.show(swapPanel, "journalCard");
        }
        else if(selectedType.equals("Book")){
            c1.show(swapPanel, "bookCard");
        }
        else if(selectedType.equals("Conference")){
            c1.show(swapPanel, "conferenceCard");
        }
	}

	/**
	 * Sets authors to the database
	 */
	private void setAuthors(){
		if(currentPublication == null){
			authorsJList.setListData(new Object[0]);
			return;
		}

		AuthorList authors = currentPublication.getAuthors();
		Object[] authorsArray = new Object[authors.size()];

		for(int index = 0; index < authors.size(); index++){
			Author a = authors.get(index);

			String authorString;

			if(authors.getStaffSubmitter() == index){
				authorString = "* ";
			}else{
				authorString = "  ";
			}

			if(a.getAuthorId() == -1){
				authorString += "  -  ";
			}else{
				authorString += " SET ";
			}

			authorsArray[index] = authorString + (a.getAuthorFirstName() + " " + a.getAuthorLastName() + " " + a.getOrganisation());
		}
		authorsJList.setListData(authorsArray);
	}

	/**
	 * Enables all of the elements in the GUI
	 * @param enabled
	 */
	private void enableGui(boolean enabled) {
		doiField.setEnabled(enabled);
		articleTitleField.setEnabled(enabled);
		authorsJList.setEnabled(enabled);
		bookDateField.setEnabled(enabled);
		bookEditionField.setEnabled(enabled);
		bookEditorsField.setEnabled(enabled);
		bookIssnIsbnField.setEnabled(enabled);
		bookPagesField.setEnabled(enabled);
		publisherField.setEnabled(enabled);
		bookUrlField.setEnabled(enabled);
		conferenceDateField.setEnabled(enabled);
		conferenceDatesField.setEnabled(enabled);
		conferenceEditionField.setEnabled(enabled);
		conferenceEditorsField.setEnabled(enabled);
		conferenceIssnIsbnField.setEnabled(enabled);
		conferenceLocationField.setEnabled(enabled);
		conferencePagesField.setEnabled(enabled);
		conferenceUrlField.setEnabled(enabled);
		confidentialBox.setEnabled(enabled);
		issnIsbnField.setEnabled(enabled);
		descriptionArea.setEnabled(enabled);
		keywordsField.setEnabled(enabled);
		journalDateField.setEnabled(enabled);
		journalIssueField.setEnabled(enabled);
		pagesField.setEnabled(enabled);
		journalTitleField.setEnabled(enabled);
		bookTitleField.setEnabled(enabled);
		journalUrlField.setEnabled(enabled);
		journalVolumeField.setEnabled(enabled);
		paperTitleField.setEnabled(enabled);
		placePubishedField.setEnabled(enabled);
		proceedingsField.setEnabled(enabled);
		publicationTypeDropDown.setEnabled(enabled);
		qaBox.setEnabled(enabled);
		rimsIdField.setEnabled(enabled);
		authorsJList.setEnabled(enabled);
		setSubmitterButton.setEnabled(enabled);
		setAuthorButton.setEnabled(enabled);
		researchProfCommDropDown.setEnabled(enabled);
		journalPublisherField.setEnabled(enabled);
		addAuthorButton.setEnabled(enabled);
		removeAuthorButton.setEnabled(enabled);
		moveAuthorDownButton.setEnabled(enabled);
		moveAuthorUpButton.setEnabled(enabled);
		journalUrlLabel.setEnabled(enabled);
		bookUrlLabel.setEnabled(enabled);
		conferenceUrlLabel.setEnabled(enabled);
	}

	/**
	 * Performs the appropriate action after an action event occurs
	 */
	@Override
	public void actionPerformed(ActionEvent e) {
		if(e.getSource() == newMenuItem){
			enableGui(false);

			if(!promptForUnsetAuthors())
				return;
			main.processDoi();
			if(currentPublication != null){
				enableGui(true);
			}
		}else if(e.getSource() == openMenuItem){

			if(!promptForUnsetAuthors())
				return;

			enableGui(false);

			main.openPublication();

			if(currentPublication != null)
				enableGui(true);

		}else if(e.getSource() == outputMenuItem){
			if(!promptForUnsetAuthors())
				return;

			main.outputPublication();
		}else if(e.getSource() == settingsMenuItem){
			main.updateSettings();
		}else if(e.getSource() == saveMenuItem){
			if(!promptForUnsetAuthors())
				return;
			main.savePublication();
			setPublication(currentPublication);
			deleteMenuItem.setEnabled(true);
		}else if(e.getSource() == helpMenuItem){

			URI uri = null;

			try {
				uri = new URI("http://teamawesomeisgreat.ueuo.com/help.html");
			} catch (URISyntaxException ex) {
				return;
			}

			try{
			Desktop.getDesktop().browse(uri);
		} catch (IOException ex) {
			JOptionPane.showMessageDialog(this,"Could not open browser.");
		}
		}else if(e.getSource() == exitMenuItem){
			main.exit();
		}if(e.getSource() == setAuthorButton){
			main.setAuthor();
			setAuthors();
		}else if(e.getSource() == setSubmitterButton){
			int selectedIndex = authorsJList.getSelectedIndex();

			if(selectedIndex == -1)
				return;

			currentPublication.getAuthors().setStaffSubmitter(selectedIndex);
			setAuthors();
			authorsJList.setSelectedIndex(selectedIndex);
		}else if(e.getSource() == moveAuthorUpButton){
            int selectedIndex = authorsJList.getSelectedIndex();

            if(selectedIndex == -1 || selectedIndex == 0)
                return;

            AuthorList authors = currentPublication.getAuthors();
            int staffSubmitter = authors.getStaffSubmitter();

            Author selectedAuthor = authors.get(selectedIndex);
            Author nextAuthor = authors.get(selectedIndex - 1);

            authors.set(selectedIndex, nextAuthor);
            authors.set(selectedIndex - 1, selectedAuthor);

            if(staffSubmitter == selectedIndex)
                authors.setStaffSubmitter(selectedIndex - 1);
            else if(staffSubmitter == selectedIndex - 1)
                authors.setStaffSubmitter(selectedIndex);

            setAuthors();
            authorsJList.setSelectedIndex(selectedIndex - 1);

		}else if(e.getSource() == moveAuthorDownButton){
            int selectedIndex = authorsJList.getSelectedIndex();


            if(selectedIndex == -1 || selectedIndex == currentPublication.getAuthors().size() - 1)
                return;

            AuthorList authors = currentPublication.getAuthors();
            int staffSubmitter = authors.getStaffSubmitter();

            Author selectedAuthor = authors.get(selectedIndex);
            Author previousAuthor = authors.get(selectedIndex + 1);

            authors.set(selectedIndex, previousAuthor);
            authors.set(selectedIndex + 1, selectedAuthor);

            if(staffSubmitter == selectedIndex)
                authors.setStaffSubmitter(authors.getStaffSubmitter() + 1);
            else if(staffSubmitter == selectedIndex + 1)
                authors.setStaffSubmitter(selectedIndex);

            setAuthors();
            authorsJList.setSelectedIndex(selectedIndex + 1);
		}else if(e.getSource() == addAuthorButton){
			Author newAuthor = CreateAuthorDialog.showDialog(this, null, "New Author");

			if(newAuthor == null)
				return;
			currentPublication.getAuthors().add(newAuthor);
			setAuthors();
		}else if(e.getSource() == removeAuthorButton){
			int selectedIndex = authorsJList.getSelectedIndex();

			if(selectedIndex == -1)
				return;

			currentPublication.getAuthors().remove(selectedIndex);
			setAuthors();
		}else if(e.getSource() == deleteMenuItem){
			enableGui(false);

			if(JOptionPane.showConfirmDialog(this, "Delete open publication?", "Delete", JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION){
				enableGui(true);
				return;
			}
			main.deletePublication();
		}
	}

	/**
	 * Returns progress bar
	 */
	@Override
	public JProgressBar getProgressBar() {
		return progressBar;
	}

	@Override
	public void lostOwnership(Clipboard arg0, Transferable arg1) {}

	/**
	 * When copy mode is enabled, once a field is clicked the contents are
	 * added to the clipboard
	 */
	@Override
	public void focusGained(FocusEvent event) {
		if(!copyModeMenuItem.isSelected())
			return;

		Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();

		if(event.getComponent() == descriptionArea){
			clipboard.setContents(new StringSelection(descriptionArea.getText()), this);
		}else{
			JTextField field = (JTextField) event.getComponent();
			clipboard.setContents(new StringSelection(field.getText()), this);
		}
	}


	@Override
	public void focusLost(FocusEvent arg0) {}

	/**
	 * When copy mode is enabled, once a field is clicked the contents are
	 * added to the clipboard
	 */
	@Override
	public void valueChanged(ListSelectionEvent e) {
		if(!copyModeMenuItem.isSelected())
			return;

		int selectedIndex = authorsJList.getSelectedIndex();

		if(selectedIndex == -1)
			return;

		Author author = currentPublication.getAuthors().get(selectedIndex);
		Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
		if(author.getUserId().equals(""))
			clipboard.setContents(new StringSelection(author.getAuthorFirstName() + " " + author.getAuthorLastName()), this);
		else
			clipboard.setContents(new StringSelection(author.getUserId()), this);
	}

	@Override
	public void mouseClicked(MouseEvent arg0) {}

	/**
	 * Causes the URL labels to turn red on a mouse over
	 */
	@Override
	public void mouseEntered(MouseEvent arg0) {
		journalUrlLabel.setForeground(Color.red);
		bookUrlLabel.setForeground(Color.red);
		conferenceUrlLabel.setForeground(Color.red);
	}

	/**
	 * Causes the URL label to return to blue on the exit of the mouse
	 */
	@Override
	public void mouseExited(MouseEvent arg0) {
		journalUrlLabel.setForeground(Color.blue);
		bookUrlLabel.setForeground(Color.blue);
		conferenceUrlLabel.setForeground(Color.blue);
	}

	@Override
	public void mousePressed(MouseEvent arg0) {}

	/**
	 * Opens the default web browser and searches the given URL
	 */
	@Override
	public void mouseReleased(MouseEvent arg0) {
		if(currentPublication == null)
			return;

		URI uri = null;

		try {
			uri = new URI(currentPublication.getUrl());
		} catch (URISyntaxException e) {
			return;
		}

		try {
			Desktop.getDesktop().browse(uri);
		} catch (IOException e) {
			JOptionPane.showMessageDialog(this,"Could not open browser.");
		}
	}

	/**
	 * Clears all the fields on the user interface
	 */
	private void clearGui(){
		setCardLayout("journal");
		journalTitleField.setText("");
		articleTitleField.setText("");
		journalUrlField.setText("");
		journalIssueField.setText("");
		pagesField.setText("");
		journalDateField.setText("");
		issnIsbnField.setText("");
		journalVolumeField.setText("");
		journalPublisherField.setText("");
		bookTitleField.setText("");
		publisherField.setText("");
		placePubishedField.setText("");
		bookUrlField.setText("");
		bookEditorsField.setText("");
		bookEditionField.setText("");
		bookIssnIsbnField.setText("");
		bookPagesField.setText("");
		bookDateField.setText("");
		publisherField.setText("");
		paperTitleField.setText("");
		proceedingsField.setText("");
		conferenceLocationField.setText("");
		conferenceDatesField.setText("");
		conferenceUrlField.setText("");
		conferenceEditorsField.setText("");
		conferenceEditionField.setText("");
		conferenceIssnIsbnField.setText("");
		conferencePagesField.setText("");
		conferenceDateField.setText("");
		doiField.setText("");
		setAuthors();
		descriptionArea.setText("");
		keywordsField.setText("");
		researchProfCommDropDown.setSelectedItem("Research");
		qaBox.setSelected(false);
		confidentialBox.setSelected(false);
		rimsIdField.setText("");
		setCharacterCountLabel();
	}



	private boolean checkAuthors(){
		if(currentPublication == null)
			return true;

		AuthorList authors = currentPublication.getAuthors();

		for(int index = 0 ; index < authors.size(); index++){
			if(authors.get(index).getAuthorId() < 0)
				return false;
		}

		return true;
	}

	@Override
	public void windowActivated(WindowEvent arg0) {}

	@Override
	public void windowClosed(WindowEvent arg0) {}

	@Override
	public void windowClosing(WindowEvent arg0) {
		main.exit();
	}

	@Override
	public void windowDeactivated(WindowEvent arg0) {}

	@Override
	public void windowDeiconified(WindowEvent arg0) {}

	@Override
	public void windowIconified(WindowEvent arg0) {}

	@Override
	public void windowOpened(WindowEvent arg0) {}

	private boolean promptForUnsetAuthors(){
		if(currentPublication != null){
			String message = "";

			if(!checkAuthors()){
				message = "Some Authors are not set.\n" ;
			}

			if(currentPublication.getAuthors().getStaffSubmitter() < 0){
				message += "The staff submitter is not set.\n";
			}

			if(!message.equals("")){
				if(JOptionPane.showConfirmDialog(this, message + "Would you like to continue?", "Continue", JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION){
					return false;
				}
			}
		}
		return true;
	}
}
